﻿Imports IIC.Forms.Edit
Imports IIC.Forms.List
Imports System.Xml
Imports System.Reflection
Imports CrystalReportViewer
Imports org.codegen.common.Encryption

Public Class frmMain

    Private Const VIEW_STUDENT As Integer = 0
    Private Const VIEW_PERIODS As Integer = 1
    Private Const VIEW_DIPLOMAS As Integer = 2
    Private Const VIEW_LESSONS As Integer = 3
    Private Const VIEW_CERTS As Integer = 4

#Region "Constructor"

    ''' <summary>
    ''' Dictionary to handle showing Administration forms in modal mode
    ''' To setup and show a new administration form:
    ''' 1. Run code generator to generate the form.
    '''    Edit the form and set Text and Size and other properties
    ''' 2. Add a new sub-menu under "Administration" menu on frm main
    ''' 3. On sub new() of frmMain, add the new sub menu and the new form's type to the "AdminMap" dictionary
    ''' </summary>
    ''' <remarks></remarks>
    Private AdminMap As Dictionary(Of ToolStripMenuItem, Type)

    Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        AdminMap = New Dictionary(Of ToolStripMenuItem, Type)
        AdminMap.Add(Me.tsmiAdminCountries, GetType(frmCountryList))
        AdminMap.Add(Me.tsmiAdminExamCenters, GetType(frmExamCenterList))
        'AdminMap.Add(Me.tsmiAdminGradeMapping, GetType(frmGradeMappingList))

        AdminMap.Add(Me.tsmiAdminCertificationsType, GetType(frmCertificationTypeList))
        AdminMap.Add(Me.tsmiAdminDiplomaType, GetType(frmDiplomaTypeList))
        AdminMap.Add(Me.tsmiAdminDistricts, GetType(frmDistrictList))
        AdminMap.Add(Me.tsmiAdminDiplomaSuperTypes, GetType(frmDiplomaSuperTypeList))

        For Each mi As ToolStripMenuItem In Me.AdminMap.Keys

            AddHandler mi.Click, AddressOf adminMenuItemClick

        Next

    End Sub
#End Region

#Region "Form Events"


    Private Sub frmPeriodTree_FormClosed(ByVal sender As Object, _
              ByVal e As FormClosedEventArgs) Handles Me.FormClosed

        'make sure that all forms are closed!
        Do While My.Application.OpenForms.Count > 0
            My.Application.OpenForms(0).Close()
        Loop

        If e.CloseReason <> CloseReason.ApplicationExitCall Then
            Application.Exit()
        End If


    End Sub

    Private Sub frmMain_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing

        Dim sLastBkDate As String = My.Settings.dbLastBackupDate
        If String.IsNullOrEmpty(sLastBkDate) Then
            sLastBkDate = "01012013"
        End If

        Dim lastBackupdate As Date = DateTime.ParseExact(sLastBkDate, "ddMMyyyy", Nothing)

        If (lastBackupdate < DateAdd(DateInterval.Day, -7, Date.Today)) Then

            Dim msg As String = String.Format("Last backup was done on {0}.  Do you want to backup now?", _
                                              Format(lastBackupdate, "dd/MM/yyyy"))

            If winUtils.MsgboxQuestion(msg) = vbYes Then

                Dim dbbackup As New DBBackup
                AddHandler dbbackup.BackupFinished, AddressOf backupFinishedOnExitApplication

                dbbackup.doBackup()
                e.Cancel = True
                Exit Sub
            End If

        End If

        Me.clearPanel2Controls()

    End Sub

    Private Sub frmPeriodTree_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        Me.tsUser.Alignment = ToolStripItemAlignment.Right
        Me.tsUser.Text = "System User: " & ModelContext.CurrentUser.UserName
        Me.setErrorStatusText(String.Empty)

        If Me.DesignMode = False Then

            For Each ts As ToolStripItem In cmdNew.DropDownItems
                Me.mnNew.DropDownItems.Add(New ToolStripMenuItem(ts.Text, Nothing, AddressOf cmdNewMenuClick, ts.Name & "1"))
            Next

            AddHandler Me.ucSystemTree.tsMnAdd.Click, AddressOf TreeMenuAddClick
            AddHandler Me.ucSystemTree.tsMnAdd2.Click, AddressOf TreeMenuAdd2Click
            AddHandler Me.ucSystemTree.tsMnAdd3.Click, AddressOf TreeMenuAdd3Click

            AddHandler Me.ucSystemTree.tsMnRemove.Click, AddressOf TreeMenuRemoveClick

            'try to select the currentperiodid node
            Dim CurrentPeriodIdSett As String = CStr(My.Settings.CurrentPeriodId)
            If CInt(CurrentPeriodIdSett) > 0 Then
                Me.ucSystemTree.tvMain.SelectedNode = Me.ucSystemTree.tvMain.Nodes(ucSystemTree.STR_ND_PERIOD_ROOT)
                Me.ucSystemTree.tvMain.SelectedNode.Expand()
                Dim prd As Period = PeriodDataUtils.findByKey(My.Settings.CurrentPeriodId)
                For Each tnd As TreeNode In Me.ucSystemTree.tvMain.SelectedNode.Nodes
                    If tnd.Name = CStr(prd.DiplomaSuperTypeId.GetValueOrDefault) Then
                        tnd.Expand()
                        For Each periodNode As TreeNode In tnd.Nodes
                            If periodNode.Name = CurrentPeriodIdSett Then
                                periodNode.Expand()
                                Me.ucSystemTree.tvMain.SelectedNode = periodNode
                                Exit For
                            End If
                        Next
                        Exit For
                    End If
                Next

            Else
                Me.ucSystemTree.tvMain.SelectedNode = Me.ucSystemTree.tvMain.Nodes(ucSystemTree.STR_ND_PERIOD_ROOT)
            End If


            Call Me.buildReportMenu()
            Call Me.setCurrentPeriodHeading()

            'If My.Settings.dasUpdatedDone <> 1 Then

            '    Me.Refresh()

            '    Dim prg As New BackroundProgressIndicator.BackroundProgressIndicator
            '    Dim dasUpdate As New My.DASUpdate
            '    prg.showCancel = False
            '    prg.progressWindowTitle = "Fixing ΔΑΣ Periods"
            '    prg.Start(AddressOf dasUpdate.doUpdate)

            'End If

        End If

    End Sub
#End Region

#Region "Add to tree"

    Private Sub AddOneOrMoreClassMembers()

        Dim periodClass As PeriodClass = CType(Me.ucSystemTree.tvMain.SelectedNode.Tag,  _
                PeriodClass)

        Dim cms As New UIClassMemberSelector()
        If cms.selectMembers(periodClass) Then
            Me.RefreshNumberOfRecordsLabel()
            Me.setStatusText("New Class Member(s) Added")
        End If


    End Sub

    Private Sub AddNewPeriodClass(ByVal currentNodeTag As Object)

        Dim cperiod As Period = CType(currentNodeTag, Period)
        If cperiod.IsOpen.GetValueOrDefault = False Then
            Call winUtils.MsgboxStop("Cannot add a class to a closed period.")
            Return
        End If

        Using f As New frmPeriodClassDetails

            f.IdValue = 0
            f.LoadData()
            f.Period = cperiod

            If f.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Me.ucSystemTree.addPeriodClass(CType(f.UcPeriodClass.ModelObject, PeriodClass))
                Me.setStatusText("New Class Added")
            End If

        End Using


    End Sub
    Private Sub addNewCertificateRequirement(ByVal CertificationTypeId As Integer)

        Dim f As New frmCertificationRequirementDetails

        f.IdValue = 0
        f.LoadData()
        f.UcCertificationRequirement.CertificationTypeId.Value = CertificationTypeId
        f.UcCertificationRequirement.CertificationTypeId.ReadOnly = True

        If f.ShowDialog() = DialogResult.OK Then
            Me.ucSystemTree.addCertRequirement(CType(f.UcCertificationRequirement.ModelObject,  _
                                                  CertificationRequirement))
            Me.setStatusText("New Certificate Requirement Added")
        End If

        f.Dispose()

    End Sub
    Private Sub AddDiplomaRequirement(ByVal dtypeid As Integer)
        'add a diploma requirement
        Dim f As New frmDiplomaRequirementDetails

        f.IdValue = 0
        f.LoadData()

        f.UcDiplomaRequirement.DiplomaTypeId.Value = dtypeid
        f.UcDiplomaRequirement.DiplomaTypeId.ReadOnly = True

        If f.ShowDialog() = DialogResult.OK Then
            Me.ucSystemTree.addDiplomaRequierment(CType(f.UcDiplomaRequirement.ModelObject,  _
                                                  DiplomaRequirement))
            Me.setStatusText("New Diploma Requirement Added")
        End If

        f.Dispose()
    End Sub
#End Region

#Region "Tree context menu click handlers"

    Public Sub TreeMenuRemoveClick(ByVal sender As Object, ByVal e As System.EventArgs)

        If Me.ucSystemTree.tvMain.SelectedNode Is Nothing Then
            Call winUtils.MsgboxStop("Please select a node from the tree view")
            Return
        End If

        Dim currentNode As TreeNode = Me.ucSystemTree.tvMain.SelectedNode
        Dim currentNodeObject As Object = Me.ucSystemTree.tvMain.SelectedNode.Tag

        'remove button clicked

        If TypeOf currentNodeObject Is ClassMember Then
            'remove class member
            If winUtils.MsgboxQuestion("Are you sure you want to remove this student from this class?") <> MsgBoxResult.Yes Then
                Return
            End If

            Dim po As ClassMember = CType(currentNodeObject, ClassMember)
            Call ClassMemberDataUtils.deleteClassMember(po)

            'need to update period node...

        ElseIf TypeOf currentNodeObject Is Lecture Then
            Dim po As Lecture = CType(currentNodeObject, Lecture)
            If po.Members.Count > 0 Then
                Call winUtils.MsgboxStop("Cannot remove a Lecture with assigned members.")
                Return
            End If

            If winUtils.MsgboxQuestion("Are you sure you want to remove this Lecture?") <> MsgBoxResult.Yes Then
                Return
            End If
            Call LectureDataUtils.deleteLecture(po)

        ElseIf TypeOf currentNodeObject Is PeriodClass Then
            Dim po As PeriodClass = CType(currentNodeObject, PeriodClass)
            If po.Members.Count > 0 Then
                Call winUtils.MsgboxStop("Cannot remove a Class with assigned members.")
                Return
            End If

            'remove Class 
            If winUtils.MsgboxQuestion("Are you sure you want to remove this class?") <> MsgBoxResult.Yes Then
                Return
            End If
            Dim p As Period = po.Period
            Dim pn As TreeNode = currentNode.Parent
            Call PeriodClassDataUtils.deletePeriodClass(po)
            Call Me.ucSystemTree.updateParentPeriodClassNode(pn, p)

        ElseIf TypeOf currentNodeObject Is Period Then
            Dim cperiod As Period = CType(currentNodeObject, Period)
            Dim studentCount As Integer = cperiod.totalStudentCount
            If cperiod.IsOpen.GetValueOrDefault = False OrElse studentCount > 0 Then
                Call winUtils.MsgboxStop("Cannot remove a closed period, or a period with Classes and Students.")
                Return
            End If
            'remove period 
            If winUtils.MsgboxQuestion("Are you sure you want to remove this Period?") <> MsgBoxResult.Yes Then
                Return
            End If

            Dim po As Period = cperiod
            Call PeriodDataUtils.deletePeriod(po)

        ElseIf TypeOf currentNodeObject Is DiplomaType Then
            If winUtils.MsgboxQuestion("Are you sure you want to remove this Diploma?") <> MsgBoxResult.Yes Then
                Return
            End If
            Dim po As DiplomaType = CType(currentNodeObject, DiplomaType)
            Call DiplomaTypeDataUtils.deleteDiplomaType(po)


        ElseIf TypeOf currentNodeObject Is DiplomaRequirement Then
            If winUtils.MsgboxQuestion("Are you sure you want to remove this Diploma Requirement?") <> MsgBoxResult.Yes Then
                Return
            End If
            Dim po As DiplomaRequirement = CType(currentNodeObject, DiplomaRequirement)

            'get the parent Period object from the parent tag
            Dim dipl As DiplomaType = CType(currentNode.Parent.Tag, DiplomaType)
            dipl.RemoveDiplomaRequirement(po)
            Call DiplomaTypeDataUtils.saveDiplomaType(dipl)


        ElseIf TypeOf currentNodeObject Is CertificationRequirement Then
            If winUtils.MsgboxQuestion("Are you sure you want to remove this Certification Requirement?") <> MsgBoxResult.Yes Then
                Return
            End If
            Dim po As CertificationRequirement = _
              CType(currentNodeObject, CertificationRequirement)

            Dim cert As CertificationType = po.Certification
            cert.RemoveCertificationRequirement(po)
            Call CertificationTypeDataUtils.saveCertificationType(cert)

        Else
            Return 'exit here! we do not want to remove the currently selected row
        End If

        Dim rowToRemove As TreeNode = Me.ucSystemTree.tvMain.SelectedNode
        'select the parent node, and remove the selected tree node!
        Me.ucSystemTree.tvMain.SelectedNode = Me.ucSystemTree.tvMain.SelectedNode.Parent
        rowToRemove.Remove()

    End Sub

    Public Sub TreeMenuAdd2Click(ByVal sender As Object, ByVal e As System.EventArgs)

        If Me.ucSystemTree.tvMain.SelectedNode Is Nothing Then
            Call winUtils.MsgboxStop("Please select a node from the tree view")
            Return
        End If

        Dim currentNode As TreeNode = Me.ucSystemTree.tvMain.SelectedNode
        Dim currentNodeTag As Object = Me.ucSystemTree.tvMain.SelectedNode.Tag

        If TypeOf currentNodeTag Is DiplomaType Then
            'create a new cert and addit as a requirement to the diploma
            Dim ct As CertificationType = Me.addNewCertificate()
            If ct IsNot Nothing Then

                Dim dr As DiplomaRequirement = DiplomaRequirementFactory.Create
                dr.Certification = ct

                CType(currentNodeTag, DiplomaType).AddCertificationRequirement(ct)
                Call DiplomaTypeDataUtils.saveDiplomaType(CType(currentNodeTag, DiplomaType))
                Call Me.ucSystemTree.addDiplomaRequierment(dr)

            End If

        ElseIf TypeOf currentNodeTag Is PeriodClass Then
            'edit class
            Call editClass(CType(currentNodeTag, PeriodClass))

        ElseIf TypeOf currentNodeTag Is Lecture Then
            'edit lecture
            Dim ct As Lecture = editLecture(CType(currentNodeTag, Lecture))
            If ct IsNot Nothing Then
                Call Me.ucSystemTree.addPeriodLecture(ct)
            End If

        ElseIf TypeOf currentNodeTag Is Period Then
            'if current node is a Period, we will add a new lecture
            Dim ct As Lecture = Me.addNewLecture()
            If ct IsNot Nothing Then
                Call Me.ucSystemTree.addPeriodLecture(ct)
            End If

        ElseIf TypeOf currentNodeTag Is DiplomaRequirement Then
            'if current node is a DiplomaRequirement, then we have a certification
            'create a new lesson and add it as a requirement to the certification of 
            'the DiplomaRequirement
            Dim ct As Lesson = Me.addNewLesson()
            If ct IsNot Nothing Then

                Dim dr As CertificationRequirement = CertificationRequirementFactory.Create
                dr.LessonId = ct.LessonId

                CType(currentNodeTag, DiplomaRequirement).Certification.AddCertificationRequirement(dr)
                Call CertificationRequirementDataUtils.saveCertificationRequirement(dr)
                Call Me.ucSystemTree.addCertRequirement(dr)

            End If

        End If
    End Sub


    ''' <summary>
    ''' Handles the Add and remove buttons of the tree context view.
    ''' </summary>
    ''' <param name="sender">Button that sent the event, Me.ucPeriodTree.tsMnAdd or Me.ucPeriodTree.tsMnRemove </param>
    ''' <param name="e"></param>
    ''' <remarks>
    ''' If the button is Add and selectedNode is ClassMember, we open up 
    ''' form frmAddStudents
    ''' </remarks>
    Private Sub TreeMenuAddClick(ByVal sender As Object, ByVal e As System.EventArgs)

        If Me.ucSystemTree.tvMain.SelectedNode Is Nothing Then
            Call winUtils.MsgboxStop("Please select a node from the tree view")
            Return
        End If

        Dim currentNode As TreeNode = Me.ucSystemTree.tvMain.SelectedNode
        Dim currentNodeTag As Object = Me.ucSystemTree.tvMain.SelectedNode.Tag


        'add button clicked
        If currentNode Is Me.ucSystemTree.tvMain.Nodes(ucSystemTree.STR_ND_PERIOD_ROOT) Then
            Me.addNewPeriod()

        ElseIf currentNode Is Me.ucSystemTree.tvMain.Nodes(ucSystemTree.STR_ND_LESSON_ROOT) Then
            Me.addNewLesson()

        ElseIf currentNode Is Me.ucSystemTree.tvMain.Nodes(ucSystemTree.STR_ND_DIPLOMA_ROOT) Then
            Me.addNewDiploma()

        ElseIf currentNode Is Me.ucSystemTree.tvMain.Nodes(ucSystemTree.STR_ND_STUDENT_ROOT) Then
            Me.addNewStudent()

        ElseIf TypeOf currentNodeTag Is DiplomaSuperType Then
            Me.addNewPeriod(CType(currentNodeTag, DiplomaSuperType).DiplomaSuperTypeId)

        ElseIf TypeOf currentNodeTag Is ClassMember Then

        ElseIf TypeOf currentNodeTag Is Lecture Then
            If TypeOf (Me.scContent.Panel2.Controls(0)) Is frmBaseGrid Then
                'call "new" routine
                CType(Me.scContent.Panel2.Controls(0), frmBaseGrid).ListEditRecord(0)

            End If

        ElseIf TypeOf currentNodeTag Is PeriodClass Then
            'add one or more class members!
            Me.AddOneOrMoreClassMembers()

        ElseIf TypeOf currentNodeTag Is Period Then
            'add a new period class
            Me.AddNewPeriodClass(currentNodeTag)

        ElseIf TypeOf currentNodeTag Is DiplomaType Then
            'add a diploma requirement
            Dim dtype As DiplomaType = CType(currentNodeTag, DiplomaType)
            Dim dtypeid As Integer = dtype.DiplomaTypeId

            Me.AddDiplomaRequirement(dtypeid)

        ElseIf TypeOf currentNodeTag Is DiplomaRequirement Then
            'add a lesson as certification requirement
            Dim dtype As DiplomaRequirement = CType(currentNodeTag, DiplomaRequirement)
            Me.addNewCertificateRequirement(dtype.CertificationTypeId.GetValueOrDefault)

        ElseIf TypeOf currentNodeTag Is CertificationRequirement Then
            'we are sitting on a certification requirement node.
            'a a new lesson requirement to the certification of the requirement
            Dim certReq As CertificationRequirement = CType(currentNodeTag, CertificationRequirement)
            Me.addNewCertificateRequirement(certReq.CertificationTypeId.GetValueOrDefault)

        End If

    End Sub
#End Region

#Region "Node selected handlers"

    'see: tsComboView_Click
    Private doNotProcessViewEvent As Boolean = False

    ''' <summary>
    ''' after selection of item by mouse, sunchronize view compo box display
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub synchronizeViewCombo(ByVal newIndex As Integer)

        Try
            Me.doNotProcessViewEvent = True
            Me.tsComboView.SelectedIndex = newIndex

        Finally
            Me.doNotProcessViewEvent = False
        End Try

    End Sub

    Private Sub StudentRootNodeSelected() Handles ucSystemTree.StudentRootNodeSelected

        Me.changePanel2ToForm(New frmStudentList)
        Call synchronizeViewCombo(VIEW_STUDENT)

    End Sub

    Private Sub MemberRootNodeSelected() Handles ucSystemTree.MemberRootNodeSelected

        Dim frmMemberList As frmMemberList = New frmMemberList
        Me.changePanel2ToForm(frmMemberList)
        Call synchronizeViewCombo(VIEW_STUDENT)

    End Sub

    Private Sub periodrootNodeSelected() Handles ucSystemTree.PeriodRootNodeSelected

        Me.changePanel2ToForm(New frmPeriodList)
        Call synchronizeViewCombo(VIEW_PERIODS)

    End Sub

    Private Sub LessonRootNodeSelected() Handles ucSystemTree.LessonRootNodeSelected

        Me.changePanel2ToForm(New frmLessonList())
        Call synchronizeViewCombo(VIEW_LESSONS)

    End Sub


    Private Sub ucPeriodTree_DiplomaRootNodeClicked() _
       Handles ucSystemTree.DiplomaRootNodeSelected

        Me.changePanel2ToForm(New frmDiplomaTypeList())
        Call synchronizeViewCombo(VIEW_DIPLOMAS)

    End Sub


    Private Sub ucPeriodTree_NodeSelected(ByVal sender As Object, _
                                        ByVal e As TreeViewEventArgs) _
                                        Handles ucSystemTree.TreeChildNodeSelected

        Me.clearPanel2Controls()

        If e.Node Is Nothing Then Return

        If TypeOf (e.Node.Tag) Is DiplomaRequirement Then
            Call synchronizeViewCombo(VIEW_DIPLOMAS)

            Dim dt As DiplomaRequirement = CType(e.Node.Tag, DiplomaRequirement)
            Dim f As New frmCertificationEarnedList
            f.setFilterCertificationTypeId(dt.CertificationTypeId, dt.Certification.CertificationType)
            f.grdData.loadGrid()
            f.setReadOnly()
            Me.changePanel2ToForm(f)

        ElseIf TypeOf (e.Node.Tag) Is DiplomaType Then
            Call synchronizeViewCombo(VIEW_DIPLOMAS)
            Dim dt As DiplomaType = CType(e.Node.Tag, DiplomaType)
            Dim f As New frmDiplomaEarnedList
            f.setFilterDiplomaTypeId(dt.DiplomaTypeId, dt.DiplomaType)
            f.grdData.loadGrid()
            f.setReadOnly()
            Me.changePanel2ToForm(f)

        ElseIf TypeOf (e.Node.Tag) Is CertificationRequirement Then

            Call synchronizeViewCombo(VIEW_DIPLOMAS)

            Dim creq As CertificationRequirement = CType(e.Node.Tag, CertificationRequirement)
            Dim uc As New ucLessonAttendees

            uc.grdClassesAttended.gpWhereclause = String.Format("periodid in (select periodid from period where diplomasupertypeid={0}) and (lessonid in ({1},{2},{3}))", _
                                                    creq.Certification.DiplomaSuperTypeId, _
                                                    creq.LessonId, creq.LessonIdAlternative.GetValueOrDefault, _
                                                    creq.LessonIdAlternative1.GetValueOrDefault)
            uc.grdClassesAttended.loadGrid()
            Me.changePanel2Control(uc, "List of Students that took Lesson: " & creq.LessonName)

        End If

    End Sub

    Private Sub ucPeriodTree_LectureNodeClicked(ByVal lecture As Lecture) _
                                        Handles ucSystemTree.LectureNodeSelected

        Dim f As New frmLectureStudentList
        f.ucLectureStudentList.grdLectureStudent.gpWhereclause = "lectureid=" & lecture.LectureId

        'Set the current period id.  This determines various settings in the system
        My.Settings.CurrentPeriodId = lecture.PeriodId.GetValueOrDefault
        Call Me.setCurrentPeriodHeading()
        Me.changePanel2ToForm(f)
        Call synchronizeViewCombo(VIEW_PERIODS)

    End Sub

    Private Sub ucPeriodTree_PeriodClassNodeClicked(ByVal periodClass As PeriodClass) _
     Handles ucSystemTree.PeriodClassNodeSelected

        Dim f As New frmClassMemberList
        f.PeriodClass = periodClass

        'Set the current period id.  This determines various settings in the system
        My.Settings.CurrentPeriodId = periodClass.PeriodId.GetValueOrDefault
        Call Me.setCurrentPeriodHeading()
        Me.changePanel2ToForm(f)
        Call synchronizeViewCombo(VIEW_PERIODS)

    End Sub

    Private Sub ucPeriodTree_PeriodNodeClicked(ByVal period As IICModel.BusObjects.Period) _
       Handles ucSystemTree.PeriodNodeSelected

        Dim newuc As New ucTreeViewPeriodView
        newuc.UcPeriodDetails.ModelObject = period
        newuc.UcPeriodDetails.loadData()
        'newuc.UcPeriodDetails.setReadOnly()

        newuc.UcPeriodClassList.grdPeriodClass.EditMode = System.Windows.Forms.DataGridViewEditMode.EditProgrammatically
        'newuc.UcPeriodClassList.grdPeriodClass.setEditable( _
        '        New PeriodClassDBMapper, "ExamCenterID", "ExamDateFrom", "ExamDateTo")
        'we are not ready yet to edit dates/times in grid...

        newuc.UcPeriodClassList.grdPeriodClass.gpWhereclause = "periodid=" & period.Id
        newuc.UcPeriodClassList.grdPeriodClass.loadGrid()

        'Set the current period id.  This determines various settings in the system
        My.Settings.CurrentPeriodId = period.PeriodId
        Call Me.setCurrentPeriodHeading()

        Me.changePanel2Control(newuc, "Period")
        Call synchronizeViewCombo(VIEW_PERIODS)

    End Sub

    Private Sub ucPeriodTree_DiplomaSuperTypeNodeSelected(ByVal DiplomaSuperType As IICModel.BusObjects.DiplomaSuperType) _
      Handles ucSystemTree.DiplomaSuperTypeNodeSelected

        Dim frmNewPeriodList As frmPeriodList = New frmPeriodList
        frmNewPeriodList.setDiplomaSuperType(DiplomaSuperType)

        Me.changePanel2ToForm(frmNewPeriodList, frmNewPeriodList.Text & ": " & _
                                DiplomaSuperType.DiplomaSuperTypeName)

        Call synchronizeViewCombo(VIEW_PERIODS)
    End Sub

#End Region

#Region "Panel2 Content management"

    ''' <summary>
    ''' if panel2 has a grid, it calls the reload
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub RefreshNumberOfRecordsLabel()

        If TypeOf (Me.scContent.Panel2.Controls(0)) Is frmBaseGrid Then
            CType(Me.scContent.Panel2.Controls(0), frmBaseGrid).grdData.requery()
            Me.setStatusText(CType(Me.scContent.Panel2.Controls(0), frmBaseGrid).grdData.RowCount & " Records")
        End If

    End Sub

    ''' <summary>
    ''' Removes all controls from Panel2 and calls the dispose method
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub clearPanel2Controls()

        While Me.scContent.Panel2.Controls.Count > 0
            Dim ctrl As Control = Me.scContent.Panel2.Controls(0)
            Me.scContent.Panel2.Controls.RemoveAt(0)
            ctrl.Dispose()
        End While

    End Sub

    ''' <summary>
    ''' Adds a new control to Panel2
    ''' </summary>
    ''' <param name="newuc"></param>
    ''' <remarks></remarks>
    Private Sub changePanel2Control(ByVal newuc As Control, Optional ByVal title As String = "")

        Me.clearPanel2Controls()

        newuc.Visible = True
        newuc.Name = "conrtol1"
        newuc.Dock = DockStyle.Fill
        Me.scContent.Panel2.Controls.Add(newuc)

        Me.Panel2Title.Text = CStr(IIf(String.IsNullOrEmpty(title), newuc.Text, title))

    End Sub

    ''' <summary>
    ''' Adds a form to panel2 of the form
    ''' </summary>
    ''' <param name="f">Form instance</param>
    ''' <remarks>Sets the toplevel=false and FormBorderStyle to none.</remarks>
    Private Sub changePanel2ToForm(ByVal f As frmBaseGrid, _
                                   Optional ByVal title As String = "")

        AddHandler f.grdData.RowErrorTextChanged, AddressOf gridRowErrorTextChanged
        AddHandler f.gridRowCountChanged, AddressOf gridRowCountChanged
        AddHandler f.gridSearchExecuted, AddressOf gridRowCountChanged

        f.TopLevel = False
        f.FormBorderStyle = Windows.Forms.FormBorderStyle.None
        Me.changePanel2Control(f)

        If TypeOf f Is IStudentContainingGrid Then
            f.addToGridContextMenu("View Member", AddressOf viewMember, True)
        End If

        Me.setStatusText(CStr(f.grdData.RowCount) & " Records")

    End Sub


    Private Sub viewMember(ByVal sender As System.Object, ByVal e As EventArgs)

        Dim mn As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
        Dim ctxMenu As ContextMenuStrip = CType(mn.Owner, ContextMenuStrip)
        Dim ctparent As Control = ctxMenu.SourceControl

        If TypeOf ctparent Is DataGridView Then
            Dim grid As DataGridView = CType(ctparent, DataGridView)
            If grid.SelectedRows.Count = 0 Then Exit Sub

            If grid.Columns("StudentId") IsNot Nothing Then

                Dim studentId As Integer = CInt(grid.SelectedRows(0).Cells("StudentId").Value)
                If (studentId = 0) Then Exit Sub

                Dim f As New frmStudentDetails

                f.IdValue = studentId
                f.LoadData()
                f.ShowDialog()

            End If

        End If

    End Sub

#End Region

#Region "New Drop Down Menu"

    Private Sub cmdNewMenuClick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
      Handles cmdNewPeriod.Click, cmdNewCertrficate.Click, cmdNewDiploma.Click, cmdNewStudent.Click, cmdNewLesson.Click

        Dim senderName As String = CType(sender, ToolStripItem).Name
        If senderName = "cmdNewPeriod" Or senderName = "cmdNewPeriod1" Then
            Me.addNewPeriod()

        ElseIf senderName = "cmdNewStudent" Or senderName = "cmdNewStudent1" Then
            Me.addNewStudent()

        ElseIf senderName = "cmdNewDiploma" Or senderName = "cmdNewDiploma1" Then
            Me.addNewDiploma()

        ElseIf senderName = "cmdNewCertrficate" Or senderName = "cmdNewCertrficate1" Then
            Me.addNewCertificate()

        ElseIf senderName = "cmdNewLesson" Or senderName = "cmdNewLesson1" Then
            Me.addNewLesson()

        End If

    End Sub

    Private Function editClass(ByVal mo As PeriodClass) As PeriodClass

        Dim f As Forms.Edit.frmPeriodClassDetails = Nothing
        Try
            f = New Forms.Edit.frmPeriodClassDetails
            f.IdValue = mo.Id
            f.LoadData()
            If f.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Me.RefreshNumberOfRecordsLabel()
                Return DirectCast(f.UcPeriodClass.ModelObject, PeriodClass)
            End If
        Finally
            If f IsNot Nothing Then f.Dispose()
        End Try

        Return Nothing
    End Function

    Private Function editLecture(ByVal mo As Lecture) As Lecture
        Dim f As Forms.Edit.frmLectureDetails = Nothing
        Try
            f = New Forms.Edit.frmLectureDetails
            f.IdValue = mo.Id
            f.LoadData()
            If f.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Me.RefreshNumberOfRecordsLabel()
                Return DirectCast(f.UcLecture.ModelObject, Lecture)
            End If
        Finally
            If f IsNot Nothing Then f.Dispose()
        End Try
        Return Nothing

    End Function

    Private Function addNewLesson() As Lesson

        Dim f As Forms.Edit.frmLessonDetails = Nothing
        Try
            f = New Forms.Edit.frmLessonDetails
            f.IdValue = 0
            f.LoadData()
            If f.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Me.RefreshNumberOfRecordsLabel()
                Return DirectCast(f.UcLesson.ModelObject, Lesson)
            End If
        Finally
            If f IsNot Nothing Then f.Dispose()
        End Try
        Return Nothing

    End Function

    Private Sub addNewDiploma()

        ' show the add new diplomatype form in modal form and 
        ' add the new diplomatype created
        ' to the tree view.

        Dim f As Forms.Edit.frmDiplomaTypeDetails = Nothing
        Try
            f = New Forms.Edit.frmDiplomaTypeDetails
            f.IdValue = 0
            f.LoadData()
            If f.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Me.ucSystemTree.addDiplomaType(CType(f.UcDiplomaType.ModelObject, DiplomaType))
            End If
        Finally
            If f IsNot Nothing Then f.Dispose()
        End Try

    End Sub

    Private Function addNewCertificate() As CertificationType
        ' show the add new diplomatype form in modal form and 
        ' add the new diplomatype created
        ' to the tree view.

        Dim f As Forms.Edit.frmCertificationTypeDetails = Nothing
        Try
            f = New Forms.Edit.frmCertificationTypeDetails
            f.IdValue = 0
            f.LoadData()
            If f.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Return CType(f.UcCertificationType.ModelObject, CertificationType)
            End If
        Finally
            If f IsNot Nothing Then f.Dispose()
        End Try

        Return Nothing

    End Function

    Private Sub addNewStudent()

        ' show the add new student form in modal form and 
        ' add the new student created
        ' to the tree view.

        Dim f As Forms.Edit.frmStudentDetails = Nothing
        Try
            f = New Forms.Edit.frmStudentDetails
            f.IdValue = 0
            f.LoadData()
            If f.ShowDialog() = Windows.Forms.DialogResult.OK Then
                'Me.ucPeriodTree.addStudent(CType(f.UcStudent.ModelObject, Student))
            End If
        Finally
            If f IsNot Nothing Then f.Dispose()
        End Try

    End Sub

    Private Sub addNewPeriod(Optional ByVal superTypeId As Integer? = Nothing)
        ' show the add new period form in modal form and 
        ' add the new period created
        ' to the tree view.

        Dim f As Forms.Edit.frmPeriodDetails = Nothing
        Try
            f = New Forms.Edit.frmPeriodDetails
            f.IdValue = 0
            f.LoadData()
            f.UcPeriod.DiplomaSuperTypeId.Value = superTypeId.GetValueOrDefault
            f.UcPeriod.resetLastLoadedValues()

            If f.ShowDialog() = Windows.Forms.DialogResult.OK Then
                'Me.ucSystemTree.addPeriod(CType(f.UcPeriod.ModelObject, Period))


            End If
        Finally
            If f IsNot Nothing Then f.Dispose()
        End Try
    End Sub

#End Region

#Region "Menu and tree navigation click handlers"

    Private Sub tsmiExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsmiExit.Click

        Me.Close()
        Application.Exit()

    End Sub

    Private Sub tsmiAbout_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsmiAbout.Click

        Dim f As New frmAboutBox
        f.ShowDialog()
        f.Close()
        f.Dispose()

    End Sub

    Private Sub GoStudents()
        Me.ucSystemTree.tvMain.SelectedNode = Me.ucSystemTree.tvMain.Nodes(ucSystemTree.STR_ND_STUDENT_ROOT)
    End Sub

    Private Sub GoPeriods()
        Me.ucSystemTree.tvMain.SelectedNode = Me.ucSystemTree.tvMain.Nodes(ucSystemTree.STR_ND_PERIOD_ROOT)
    End Sub
    Private Sub GoLessons()
        Me.ucSystemTree.tvMain.SelectedNode = Me.ucSystemTree.tvMain.Nodes(ucSystemTree.STR_ND_LESSON_ROOT)
    End Sub
    Private Sub GoDiplomas()
        Me.ucSystemTree.tvMain.SelectedNode = Me.ucSystemTree.tvMain.Nodes(ucSystemTree.STR_ND_DIPLOMA_ROOT)
    End Sub

    Private Sub GoCertifications()
        Me.ucSystemTree.tvMain.SelectedNode = Me.ucSystemTree.tvMain.Nodes(ucSystemTree.STR_ND_CERT_ROOT)
    End Sub

    Private Sub tsmiStudents_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsmiStudents.Click
        Me.tsComboView.SelectedIndex = 0
    End Sub

    Private Sub tsmiPeriods_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsmiPeriods.Click
        Me.tsComboView.SelectedIndex = 1
    End Sub

    Private Sub tsmiDiplomas_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsmiDiplomas.Click
        Me.tsComboView.SelectedIndex = 2
    End Sub

    Private Sub tsmiLessons_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsmiLessons.Click
        Me.tsComboView.SelectedIndex = 3
    End Sub

    Private Sub tsComboView_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
                Handles tsComboView.SelectedIndexChanged

        If Me.doNotProcessViewEvent Then Exit Sub

        If tsComboView.SelectedIndex = -1 Then
            tsComboView.SelectedIndex = 0
        End If

        Select Case tsComboView.SelectedIndex
            Case VIEW_STUDENT
                Me.GoStudents()

            Case VIEW_PERIODS
                Me.GoPeriods()

            Case VIEW_DIPLOMAS
                Me.GoDiplomas()

            Case VIEW_LESSONS
                Me.GoLessons()

            Case VIEW_CERTS
                Me.GoCertifications()

        End Select

    End Sub

    Private Sub tsmiViewHelp_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsmiViewHelp.Click

        Dim f As New frmHelp
        f.Show()

    End Sub

    'handles click of all "Administration" menu sub items
    Private Sub adminMenuItemClick(ByVal sender As Object, ByVal e As EventArgs)

        Dim f As Type = Me.AdminMap.Item(CType(sender, ToolStripMenuItem))
        If f IsNot Nothing Then

            Dim frm As Form = CType(Activator.CreateInstance(f), Form)
            Call frm.ShowDialog()
            frm.Dispose()

        End If

    End Sub


#End Region

#Region "Status Strip label"

    Public Sub setStatusText(ByVal msg As String)

        Me.tsLblStatus.Text = msg

    End Sub

    Public Sub gridRowErrorTextChanged(ByVal sender As Object, ByVal e As DataGridViewRowEventArgs)
        Me.setErrorStatusText(e.Row.ErrorText)
    End Sub

    Private Sub setErrorStatusText(ByVal tx As String)
        If String.IsNullOrEmpty(tx) Then
            Me.tsError.Text = String.Empty

        Else
            Me.tsError.Text = tx.Trim

        End If

        Me.tsError.Visible = Not String.IsNullOrEmpty(Me.tsError.Text)

    End Sub

    Private Sub tsError_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) _
        Handles tsError.DoubleClick

        Call winUtils.MsgboxInfo(Me.tsError.Text)

    End Sub

#End Region

    Private Sub buildReportMenu()

        CriterionMetadata.defaultCriterionUIHandler = IICReportsDataSourceHandler.instance

        Dim ret As List(Of ReportMatadata) = My.Application.reportsCache.getSystemReports

        For Each cr As ReportMatadata In ret
            Dim tsmi As ToolStripItem = tsmiReports.DropDownItems.Add(cr.DisplayName)
            AddHandler tsmi.Click, AddressOf tsmiReportClickHandler
            tsmi.Tag = cr.ReportKey

        Next

    End Sub

    Private Sub tsmiReportClickHandler(ByVal sender As Object, ByVal e As System.EventArgs)

        Dim tsmi As ToolStripItem = CType(sender, ToolStripItem)
        Dim rptKey As String = CStr(tsmi.Tag)

        Dim cv As New CrystalReportViewer.CRReportViewer
        Dim rpt As ReportMatadata = My.Application.reportsCache.getSystemReportByKey(rptKey)
        cv.IReportInstanceLoader = IICReportsDataSourceHandler.instance
        cv.ReportConnString = DBUtils.Current.ConnString
        cv.ReportMetaData = rpt
        cv.askForCriteriaAndShowReport()

    End Sub

    Public Sub setCurrentPeriodHeading()

        Dim stitle As String = FormsApplicationContext.current.ApplicationTitle & ", DB:[" & DBVersion.SYSTEM_DATABASE_VERSION & "]"

        If My.Settings.CurrentPeriodId <> 0 Then

            Dim p As Period = PeriodDataUtils.findByKey(My.Settings.CurrentPeriodId)
            If (p IsNot Nothing) Then
                stitle &= " - ** Current Period: " & _
                                        p.DiplomaSuperType.DiplomaSuperTypeCode & _
                                        " / " & p.PeriodDescription & " **"

            End If

        End If

        Me.Text = stitle

    End Sub

    Private Sub TreeMenuAdd3Click(ByVal sender As Object, ByVal e As EventArgs)

        If Me.ucSystemTree.tvMain.SelectedNode Is Nothing Then
            Call winUtils.MsgboxStop("Please select a node from the tree view")
            Return
        End If

        Dim currentNode As TreeNode = Me.ucSystemTree.tvMain.SelectedNode
        Dim currentNodeTag As Object = Me.ucSystemTree.tvMain.SelectedNode.Tag

        If TypeOf currentNodeTag Is Period Then
            'if current node is a Period, then we have a Period
            'we will create a new lesson and add it a class to the period
            Dim ct As Lesson = Me.addNewLesson()
            If ct IsNot Nothing Then

                Dim dr As PeriodClass = PeriodClassFactory.Create
                dr.LessonId = ct.LessonId

                CType(currentNodeTag, Period).AddClass(dr)
                Call PeriodClassDataUtils.savePeriodClass(dr)
                Call Me.ucSystemTree.addPeriodClass(dr)

            End If
        End If

    End Sub

    Private Function addNewLecture() As Lecture
        Dim f As Forms.Edit.frmLectureDetails = Nothing
        Try
            f = New Forms.Edit.frmLectureDetails
            f.IdValue = 0
            f.LoadData()
            If f.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Me.RefreshNumberOfRecordsLabel()
                Return DirectCast(f.UcLecture.ModelObject, Lecture)
            End If
        Finally
            If f IsNot Nothing Then f.Dispose()
        End Try
        Return Nothing
    End Function

    Private Sub gridRowCountChanged(ByVal sender As Object)

        Dim lSender As DataGridView = CType(sender, DataGridView)
        Dim msgstatus As String = String.Empty

        msgstatus = CStr(lSender.RowCount) & " Records"
        Dim lstatus As DataGridViewAutoFilterColumnStatus = DataGridViewAutoFilterColumnHeaderCell.GetFilterStatus(lSender)

        If Not lstatus Is Nothing Then
            Dim sfilter As String = lstatus.FilteredApplied

            If String.IsNullOrEmpty(sfilter) = False Then
                msgstatus = msgstatus & ", " & sfilter

            End If
        End If

        Me.setStatusText(msgstatus)
    End Sub


    Private Sub tsmiBackup_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsmiBackup.Click

        Dim d As New DBBackup
        AddHandler d.BackupFinished, AddressOf backupFinished
        d.doBackup()

    End Sub


    ''' <summary>
    ''' This handler is used to handle finish of backup when exiting the application
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <remarks></remarks>
    Private Sub backupFinishedOnExitApplication(ByVal sender As Object)

        If CType(sender, DBBackup).wasCancelled Then
            Call winUtils.MsgboxInfo("Backup of database was cancelled.")
        Else
            Call winUtils.MsgboxInfo("Backup of database completed sucessfully.")
            My.Settings.dbLastBackupDate = Format(Now, "ddMMyyyy")
        End If

        Application.Exit()

    End Sub

    Private Sub backupFinished(ByVal sender As Object)

        If CType(sender, DBBackup).wasCancelled Then
            Call winUtils.MsgboxInfo("Backup of database was cancelled.")
        Else
            Call winUtils.MsgboxInfo("Backup of database completed sucessfully.")
            My.Settings.dbLastBackupDate = Format(Now, "ddMMyyyy")
        End If

        If CType(sender, DBBackup).exitAfterBackup Then
            Me.Close()
        End If

    End Sub

    Private Sub tsmiRestore_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tsmiRestore.Click

        If winUtils.MsgboxQuestion("This will download and restore the backup from the website.  Are you sure?") = vbYes Then

            Dim d As New DBRestoreBackup
            d.downloadBackup()

            winUtils.MsgboxInfo("Backup File downloaded and extracted at {0}.  You need to manually run restore database command.", SimpleEncrypt.Decipher(My.Settings.dbBackupDir))

        End If

    End Sub
End Class